# -*- coding:utf-8 -*-
"""Created By Corvo"""

import random

from const import *
from ..mdk.common.utils.misc import Misc
from ..mdk.module import preset_module
from ..mdk.module.system.base import *
from ..mob.aggressive.version15 import *
from ..mob.aggressive.version6 import *
from ..mob.neutral import *
from ..modCommon.modConfig import ModEffect, ModServer, ModItem, ModEntity, ModExtraData
from ..modCommon.modEnum import ModMergeData


class DataMergeModuleServer(ModuleServerBase):
    """数据合并模块服务端"""
    __mVersion__ = 115
    __identifier__ = ModuleEnum.identifier

    def __init__(self):
        super(DataMergeModuleServer, self).__init__()
        self._merge_key = "beast"
        self._load_data = False
        self._data_uid = Misc.CreateUUID()

        self._merge_data = {"data": {}}

        self.stone_attr_key = "StoneAttrStorage"

    def ConfigEvent(self):
        super(DataMergeModuleServer, self).ConfigEvent()
        self.defaultEvent.update({
            ServerEvent.ClientLoadAddonsFinishServerEvent: self.ClientLoadAddonsFinishServerEvent,
            ServerEvent.WillAddEffectServerEvent: self.WillAddEffectServerEvent,
            ServerEvent.AddEffectServerEvent: self.AddEffectServerEvent,
            ServerEvent.RemoveEffectServerEvent: self.RemoveEffectServerEvent,
            # version 6.0 挖掘、击杀和开箱行为掉落战利品
            ServerEvent.DestroyBlockEvent: self.DestroyBlockEvent,
            ServerEvent.MobDieEvent: self.MobDieEvent,
            ServerEvent.OnContainerFillLoottableServerEvent: self.OnContainerFillLoottableServerEvent,
        })
        self.serverEvent.update({
            ModuleEvent.ModuleRequestMergeDataEvent: self.ModuleRequestMergeDataEvent,
            "ModuleRequestLootRegisterEvent": self.ModuleRequestLootRegisterEvent,
            "ModuleRequestSkillRegisterEvent": self.ModuleRequestSkillRegisterEvent,
            "ModuleRequestRenderRegisterEvent": self.ModuleRequestRenderRegisterEvent,
            "ModuleRequestQuestRegisterEvent": self.ModuleRequestQuestRegisterEvent,
            ServerEvent.ServerModuleFinishedLoadEvent: self.ServerModuleFinishedLoadEvent,
            # 免费包内容
            # "OnPlayerSummonBeastCombineEvent": self.OnPlayerSummonBeastCombineEvent,
        })

        # -----------------------------------------------------------------------------------

    def AddBigStoneEffect(self, entityId, level):
        """添加巨人之矛效果"""
        entity = LivingEntity(entityId)
        if entity.IsPlayer():
            pass
        else:
            storage = entity.GetStorage(self.stone_attr_key)
            max_health = storage.get(GameAttr.MaxHealth)
            if not max_health:
                max_health = entity.GetMaxHealth()
                entity.SetStorage(self.stone_attr_key, {GameAttr.MaxHealth: max_health})
            new_max_health = max_health * (1.0 + 0.1 * level)
            entity.SetMaxHealth(new_max_health)
            entity.AddRateHealth(0.1 * level)

        self.StartCoroutine(self._OnScaleBigAnim(entity))

    def AddSmallStoneEffect(self, entityId, level):
        """添加微缩之环效果"""
        entity = LivingEntity(entityId)
        if entity.IsPlayer():
            pass
        else:
            storage = entity.GetStorage(self.stone_attr_key)
            max_health = storage.get(GameAttr.MaxHealth)
            if not max_health:
                max_health = entity.GetMaxHealth()
                entity.SetStorage(self.stone_attr_key, {GameAttr.MaxHealth: max_health})
            new_max_health = max_health * (1.0 - 0.1 * level)
            entity.SetMaxHealth(new_max_health)
            if entity.GetHealth() >= new_max_health:
                entity.SetHealth(new_max_health)
        self.StartCoroutine(self._OnScaleSmallAnim(entity))

    @staticmethod
    def _OnScaleBigAnim(entity):
        # type: (LivingEntity) -> None
        """放大动画"""
        entity.AddTag("stone_scaling")
        for index in xrange(30):
            rate = float(index) / 30 + 1
            entity.SetScale(rate)
            yield 1
        entity.RemoveTag("stone_scaling")
        entity.RemoveTag("stone_scale_small")
        entity.AddTag("stone_scale_big")

    @staticmethod
    def _OnScaleSmallAnim(entity):
        # type: (LivingEntity) -> None
        """缩小动画"""
        entity.AddTag("stone_scaling")
        for index in xrange(30):
            rate = 1 - (index / 45.0)
            entity.SetScale(rate)
            yield 1
        entity.RemoveTag("stone_scaling")
        entity.RemoveTag("stone_scale_big")
        entity.AddTag("stone_scale_small")

    @staticmethod
    def _OnScaleResetAnim(entity):
        # type: (LivingEntity) -> None
        """恢复动画"""
        entity.AddTag("stone_scaling")
        if entity.HasTag("stone_scale_big"):
            for i in xrange(30):
                rate = 2 - 1.0 * i / 30
                entity.SetScale(rate)
                yield 1
        elif entity.HasTag("stone_scale_small"):
            base = 1.0 / 3
            for i in xrange(30):
                rate = 2.0 * i / 90 + base
                entity.SetScale(rate)
                yield 1
        else:
            yield 0
        entity.RemoveTag("stone_scaling")
        entity.RemoveTag("stone_scale_big")
        entity.RemoveTag("stone_scale_small")

    def ResetStoneAttrModify(self, entity):
        # type: (LivingEntity) ->None
        """重置原石属性修正"""
        storage = entity.GetStorage(self.stone_attr_key)
        max_health = storage.get(GameAttr.MaxHealth)
        if not max_health:
            return
        entity.SetMaxHealth(max_health)

    # -----------------------------------------------------------------------------------

    @classmethod
    def ModuleRequestLootRegisterEvent(cls, args):
        config = args["config"]  # type: list
        config.append("loot/root_beast_sec.json")
        args["config"] = config

    @classmethod
    def ModuleRequestSkillRegisterEvent(cls, args):
        config = args["config"]  # type: list
        config.append("skills/root_sec.json")
        args["config"] = config

    @classmethod
    def ModuleRequestRenderRegisterEvent(cls, args):
        config = args["config"]  # type: list
        config.append("render/root_beast_sec.json")
        args["config"] = config

    @classmethod
    def ModuleRequestQuestRegisterEvent(cls, args):
        config = args["config"]  # type: list
        config.append("quests/root_beast_sec.json")

    # -----------------------------------------------------------------------------------

    def ClientLoadAddonsFinishServerEvent(self, args):
        playerId = args["playerId"]
        if not self._load_data:
            self._merge_data = {
                "mod": self._merge_key,
                "uid": self._data_uid,
                "data": {
                    "ItemAttrConfig": ModMergeData.ItemAttrConfig,
                    "MobAttrConfig": ModMergeData.MobAttrConfig,
                    # "ClawHudMap": "",
                    "CombineEntity": ModMergeData.CombineEntity,
                    "MachineCombine": ModMergeData.MachineCombine,
                    "ThunderRaccoonEntity": ModMergeData.ThunderRaccoonEntity,
                    "ElementEssential": ModMergeData.ElementEssential,
                    "MachineSprite": ModMergeData.MachineSprite,
                    "ModuleItem": ModMergeData.ModuleItem,
                    "CaptureEntity": ModMergeData.CaptureEntity,
                    "SkillClawItem": ModMergeData.SkillClawItem,
                    "EssentialItem": ModMergeData.EssentialItem,
                    "BookEntityData": ModMergeData.BookEntityData,
                    "MiscItem": ModMergeData.MiscItem,
                    "StoneItem": ModMergeData.StoneItem
                }
            }
            ModMergeData.BookShowEntity = ModMergeData.CaptureEntity + ModMergeData.CombineEntity
            ModMergeData.MachineEntity = ModMergeData.MachineCombine + ModMergeData.MachineSprite
            self.BroadcastEvent(ModuleEvent.ModuleRequestMergeDataEvent, self._merge_data)
            self._load_data = True

            for key, value in self._merge_data["data"].iteritems():
                setattr(ModMergeData, key, value)
                if hasattr(ModExtraData, key):
                    setattr(ModExtraData, key, value)

            self.BroadcastEvent("OnModuleFinishedMergeDataEvent", {})
        self.NotifyToClient(playerId, ModuleEvent.ModuleRequestUpdateMergeDataEvent, {"data": self._merge_data["data"]})

    def ModuleRequestMergeDataEvent(self, args):
        if args["mod"] != self._merge_key or args["uid"] == self._data_uid:
            return
        for key, value in args["data"].items():
            if not hasattr(ModMergeData, key):
                continue
            data = getattr(ModMergeData, key)
            if isinstance(value, list):
                for _key in data:
                    if _key not in value:
                        value.append(_key)
            elif isinstance(value, dict):
                value.update(data)

    def WillAddEffectServerEvent(self, args):
        entityId = args["entityId"]
        effectName = args["effectName"]

    def AddEffectServerEvent(self, args):
        entityId = args["entityId"]
        effectName = args["effectName"]
        effectAmplifier = args["effectAmplifier"]

    def RemoveEffectServerEvent(self, args):
        entityId = args["entityId"]
        effectName = args["effectName"]

    def DestroyBlockEvent(self, args):
        dim = args["dimensionId"]
        block_pos = (args["x"], args["y"], args["z"])

    def MobDieEvent(self, args):
        entityId = args["id"]

    def OnContainerFillLoottableServerEvent(self, args):
        item_list = args["itemList"]  # type: list
        items = []

    def OnPlayerSummonBeastCombineEvent(self, args):
        playerId = args["playerId"]
        engine_type = args["engine_type"]

    # 模块加载完成事件
    def ServerModuleFinishedLoadEvent(self, args):
        # 生物注册
        module = self.ModuleSystem.GetModule(preset_module.MobModuleId)  # type: preset_module.MobModuleServer
        # version 6.0 -> stone
        module.RegisterMobClass(ModEntity.water_bee, WaterBee)
        module.RegisterMobClass(ModEntity.fire_sloth, FireSloth)
        module.RegisterMobClass(ModEntity.earth_bull, EarthBullEntity)
        module.RegisterMobClass(ModEntity.gold_frog, GoldFrogEntity)
        module.RegisterMobClass(ModEntity.wood_mouse, WoodManisEntity)
        module.RegisterMobClass(ModEntity.earth_chomper, EarthChomperEntity)
        module.RegisterMobClass(ModEntity.gold_chomper, GoldChomperEntity)
        module.RegisterMobClass(ModEntity.mantis_chomper, MantisChomperEntity)
        module.RegisterMobClass(ModEntity.bear_crocodile, BearCrocodileEntity)
        module.RegisterMobClass(ModEntity.bear_bull, BearBullileEntity)
        module.RegisterMobClass(ModEntity.turtle_frog, TurtleFrogEntity)
        module.RegisterMobClass(ModEntity.frog_bee, FrogBeeEntity)
        module.RegisterMobClass(ModEntity.frog_manis, FrogManisEntity)
        module.RegisterMobClass(ModEntity.sloth_manis, SlothManisEntity)
        module.RegisterMobClass(ModEntity.manis_velociraptor, ManisVelociraptorEntity)
        module.RegisterMobClass(ModEntity.snake_chomper, SnakeChomperEntity)
        module.RegisterMobClass(ModEntity.inkfish_mantis, InkfishMantisEntity)
        # module.RegisterMobClass(ModEntity.water_spider, WaterSpiderEntity)


